package org.dreamwork.jasmine2.web.client;

/*
import java.util.HashMap;
import java.util.Map;
*/
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by IntelliJ IDEA.
 * User: seth.yang
 * Date: 12-4-26
 * Time: 下午2:36
 */
public class OSParser {
/*
    private static final String[] expressions = {
        "(Windows NT 6.1; WOW64; U; zh-cn)",
        "(X11; Linux x86_64; U; en)",
        "(Android 2.2; Linux; Opera Tablet/ADR-1204201824; U; zh-cn)",
        "(X11; Linux x86_64; U; zh-cn)",
        "(Macintosh; Intel Mac OS X 10.6.7; U; zh-cn)",
        "(compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)",
        "(Windows NT 5.1; rv:11.0)",
        "(X11; U; Linux x86_64; en-US; rv:1.9.0.12)",
        "(Ubuntu; X11; Linux x86_64; rv:8.0)",
        "(Macintosh; U; Intel Mac OS X 10.6; zh-CN; rv:1.9.2.13)",
        "(Windows NT 6.1; WOW64)",
        "(Linux; U; Android 2.2; zh-cn; GT-P1000 Build/FROYO)",
        "(iPhone; CPU iPhone OS 5_1 like Mac OS X)",
        "(iPad; CPU OS 5_0_1 like Mac OS X)",
        "(Linux; U; Android 2.2; zh-cn; GT-P1000 Build/FROYO)",
        "(Windows; U; Windows NT 5.1; en-US)",
        "(Macintosh; Intel Mac OS X 10_7_3)",
        "(Windows NT 6.1)",
        "(X11; Linux x86_64)",
        "(Windows; U; Windows NT 5.1; zh-CN)",
        "(Macintosh; U; Intel Mac OS X 10_6_7; zh-cn)",
        "(Macintosh; U; Intel Mac OS X 10_6_7; en-US)",
        "(Linux; U; Android 2.3.6; zh-cn; MOT-XT883/SLNCT-60.3.250; 540*960; CTC/2.0)",
        "(X11; U; Linux i686; en-US; rv:1.9.1.4)",
    };
*/

    private static final Pattern WINDOWS = Pattern.compile (".*?Windows( NT )?([\\d\\.]+)(; )?(WOW64)?.*", Pattern.CASE_INSENSITIVE);
    private static final Pattern ANDROID = Pattern.compile (".*?Android\\s*([\\d\\.]+);.*", Pattern.CASE_INSENSITIVE);
    private static final Pattern LINUX = Pattern.compile (".*?Linux\\s*(.*?)[;\\)].*", Pattern.CASE_INSENSITIVE);
    private static final Pattern MAC = Pattern.compile (".*?Macintosh;.*?Mac OS X\\s*([\\d\\._]+).*", Pattern.CASE_INSENSITIVE);
    private static final Pattern IPHONE = Pattern.compile (".*?iPhone;.*?iPhone OS\\s*([\\d\\._]+).*?like Mac OS X.*", Pattern.CASE_INSENSITIVE);
    private static final Pattern IPAD = Pattern.compile (".*?iPad;.*?OS\\s*([\\d\\._]+).*?like Mac OS X.*", Pattern.CASE_INSENSITIVE);

    public static OperationSystem parseOS (String e) {
        e = e.trim ();
        Matcher m = WINDOWS.matcher (e);
        if (m.matches ())
            return parseWindows (m);

        m = ANDROID.matcher (e);
        if (m.matches ())
            return parseAndroid (m);

        m = LINUX.matcher (e);
        if (m.matches ())
            return parseLinux (m);

        m = MAC.matcher (e);
        if (m.matches ())
            return parseOSX (m);

        m = IPHONE.matcher (e);
        if (m.matches ())
            return parseIPhone (m);

        m = IPAD.matcher (e);
        if (m.matches ())
            return parseIPad (m);

        return OperationSystem.UNKNOWN;
    }



/*
    public static void main (String[] args) throws Exception {
        Map<String, OperationSystem> map = new HashMap<String, OperationSystem> ();
        for (String e : expressions) {
            e = e.trim ();
            Matcher m = WINDOWS.matcher (e);
            if (m.matches ()) {//map.put (e, parseWindows (m));
                OperationSystem os = parseWindows (m);
                map.put (e, os);
                System.out.println (e + " --> " + os);
                continue;
            }
            m = ANDROID.matcher (e);
            if (m.matches ()) {
                OperationSystem os = parseAndroid (m);
                map.put (e, os);
                System.out.println (e + " --> " + os);
                continue;
            }
            m = LINUX.matcher (e);
            if (m.matches ()) {
                OperationSystem os = parseLinux (m);
                map.put (e, os);
                System.out.println (e + " --> " + os);
                continue;
            }
            m = MAC.matcher (e);
            if (m.matches ()) {
                OperationSystem os = parseOSX (m);
                map.put (e, os);
                System.out.println (e + " --> " + os);
                continue;
            }
            m = IPHONE.matcher (e);
            if (m.matches ()) {
                OperationSystem os = parseIPhone (m);
                map.put (e, os);
                System.out.println (e + " --> " + os);
                continue;
            }
            m = IPAD.matcher (e);
            if (m.matches ()) {
                OperationSystem os = parseIPad (m);
                map.put (e, os);
                System.out.println (e + " --> " + os);
            }
        }
        System.out.println (map);
        System.out.println ("done");
    }
*/

    private static OperationSystem parseWindows (Matcher m) {
        OperationSystem os = new OperationSystem ();
        String version_expression = m.group (2);
        String arch = m.group (4);

        Version version = new Version (version_expression);
        os.setVersion (version);

        if (version.major == 5) os.setType (OSType.WindowsXP);
        else if (version.major == 6) {
            if (version.minor == 0) os.setType (OSType.WindowsVista);
            else if (version.minor == 1) os.setType (OSType.Windows7);
            else if (version.minor == 2) os.setType (OSType.Windows8);
        } else
            os.setType (OSType.Windows);


        if (arch != null && "WOW64".equalsIgnoreCase (arch.trim ()))
            os.setArchitecture (Architecture.X86_64);
        else
            os.setArchitecture (Architecture.X86);
        return os;
    }

    private static OperationSystem parseAndroid (Matcher m) {
        OperationSystem os = new OperationSystem ();
        os.setType (OSType.Android);
        Version version = new Version (m.group (1));
        os.setVersion (version);
        os.setArchitecture (Architecture.Android);
        return os;
    }

    private static OperationSystem parseLinux (Matcher m) {
        OperationSystem os = new OperationSystem ();
        os.setType (OSType.Linux);
        os.setVersion (Version.UNKNOWN);
        String arch = m.group (1);
        if (arch != null && "x86_64".equalsIgnoreCase (arch.trim ()))
            os.setArchitecture (Architecture.X86_64);
        else
            os.setArchitecture (Architecture.X86);
        return os;
    }

    private static OperationSystem parseOSX (Matcher m) {
        OperationSystem os = new OperationSystem ();
        os.setType (OSType.OSX);
        Version version = new Version (m.group (1).trim ());
        os.setVersion (version);
        os.setArchitecture (Architecture.X86_64);
        return os;
    }

    private static OperationSystem parseIPhone (Matcher m) {
        OperationSystem os = new OperationSystem ();
        os.setType (OSType.IOS);
        Version version = new Version (m.group (1).trim ());
        os.setVersion (version);
        os.setArchitecture (Architecture.IPhone);
        return os;
    }

    private static OperationSystem parseIPad (Matcher m) {
        OperationSystem os = new OperationSystem ();
        os.setType (OSType.IOS);
        Version version = new Version (m.group (1).trim ());
        os.setVersion (version);
        os.setArchitecture (Architecture.IPad);
        return os;
    }
}